package IC.AST;

import IC.Symbols.Symbol;
import IC.Symbols.SymbolTable;
import IC.Types.MethodType;

import java.util.List;

/**
 * Abstract base class for method AST nodes.
 * 
 * @author Tovi Almozlino
 */
public abstract class Method extends ASTNode {

	protected Type type;

	protected String name;

	protected List<Formal> formals;

	protected List<Statement> statements;

    private SymbolTable methodSymTable;

    private MethodType contextType;

    private Symbol symbolTableEntry;

    private Symbol retSymbolTableEntry;

    private Method overriddenMethod;

    /**
	 * Constructs a new method node. Used by subclasses.
	 * 
	 * @param type
	 *            Data type returned by method.
	 * @param name
	 *            Name of method.
	 * @param formals
	 *            List of method parameters.
	 * @param statements
	 *            List of method's statements.
	 */
	protected Method(Type type, String name, List<Formal> formals,
			List<Statement> statements) {
		super(type.getLine());
		this.type = type;
		this.name = name;
		this.formals = formals;
		this.statements = statements;
	}

    public SymbolTable getMethodSymTable() {
        return methodSymTable;
    }

    public void setMethodSymTable(SymbolTable methodSymTable) {
        this.methodSymTable = methodSymTable;
    }

    public Type getType() {
		return type;
	}

	public String getName() {
		return name;
	}

	public List<Formal> getFormals() {
		return formals;
	}

	public List<Statement> getStatements() {
		return statements;
	}

    public MethodType getContextType() {
        return contextType;
    }

    public void setContextType(MethodType contextType) {
        this.contextType = contextType;
    }

    public Symbol getSymbolTableEntry() {
        return symbolTableEntry;
    }

    public void setSymbolTableEntry(Symbol symbolTableEntry) {
        this.symbolTableEntry = symbolTableEntry;
    }

    public Symbol getRetSymbolTableEntry() {
        return retSymbolTableEntry;
    }

    public void setRetSymbolTableEntry(Symbol retSymbolTableEntry) {
        this.retSymbolTableEntry = retSymbolTableEntry;
    }

    public Method getOverriddenMethod() {
        return overriddenMethod;
    }

    public void setOverriddenMethod(Method overriddenMethod) {
        this.overriddenMethod = overriddenMethod;

        for (int i = 0; i < formals.size(); i++) {
            formals.get(i).setOverriddenFormal(overriddenMethod.getFormals().get(i));
        }
    }
}